package com.chuangke.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chuangke.admin.entity.SysUser;
import com.chuangke.admin.service.SysUserService;
import com.chuangke.common.db.page.CkPageQuery;
import com.chuangke.common.exception.ChuangkeException;
import com.chuangke.common.idgen.IdManager;
import com.chuangke.common.utils.SecurityUtils;
import com.chuangke.system.dao.mapper.SysOptLogMapper;
import com.chuangke.system.entity.SysOptLog;
import com.chuangke.system.enums.LogOptType;
import com.chuangke.system.service.SysOptLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SysOptLogServiceImpl implements SysOptLogService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysOptLogMapper sysOptLogMapper;

    @Override
    public void save(List<SysOptLog> sysOptLogList) {
        saveToStore(sysOptLogList);
    }

    @Async
    @Override
    public void asyncSave(List<SysOptLog> sysOptLogList) {
        saveToStore(sysOptLogList);
    }

    @Async
    @Override
    public void asyncSave(SysOptLog sysOptLog) {
        saveToStore(sysOptLog);
    }

    @Override
    public IPage<SysOptLog> findByCondition(CkPageQuery pageQuery) {
        QueryWrapper<SysOptLog> queryWrapper = new QueryWrapper<>();
        String objId = (String) pageQuery.get("objId");
        if (objId != null && !objId.trim().isEmpty()) {
            queryWrapper.lambda().eq(SysOptLog::getObjId, objId);
        }
        String optType = (String) pageQuery.get("optType");
        if (optType != null && !optType.trim().isEmpty()) {
            queryWrapper.lambda().eq(SysOptLog::getOptType, optType);
        }
        queryWrapper.lambda().orderByDesc(SysOptLog::getCreatedAt);
        IPage<SysOptLog> result = sysOptLogMapper.selectPage(pageQuery.getPage(), queryWrapper);
        List<SysOptLog> list = result.getRecords();
        loadUser(list);
        return result;
    }

    @Override
    public List<SysOptLog> findReadedByCondition(CkPageQuery pageQuery) {
        pageQuery = getSysOptLogRequest(pageQuery);
        pageQuery.put("optType", LogOptType.SELECT.name());
        QueryWrapper<SysOptLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysOptLog::getOptType, pageQuery.get("optType"));
        String objId = (String) pageQuery.get("objId");
        if (objId != null && !objId.isEmpty()) {
            queryWrapper.lambda().eq(SysOptLog::getObjId, objId);
        }
        List<SysOptLog> list = sysOptLogMapper.findReadedByCondition(queryWrapper);
        loadUser(list);

        return list;
    }

    @Override
    public List<SysOptLog> findProcessByCondition(CkPageQuery pageQuery) {
        List<SysOptLog> result = findOneReadByCondition(pageQuery);
        List<String> list = Arrays.asList(LogOptType.CREATE.name(), LogOptType.PROCESS.name());
        result = result.stream().filter(opt -> list.contains(opt.getOptType())).collect(Collectors.toList());
        return result;
    }

    @Override
    public List<SysOptLog> findOneReadByCondition(CkPageQuery pageQuery) {
        pageQuery = getSysOptLogRequest(pageQuery);
        pageQuery.put("optType", LogOptType.SELECT.name());
        QueryWrapper<SysOptLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysOptLog::getOptType, pageQuery.get("optType"));
        String objId = (String) pageQuery.get("objId");
        if (objId != null && !objId.isEmpty()) {
            queryWrapper.lambda().eq(SysOptLog::getObjId, objId);
        }
        List<SysOptLog> list = sysOptLogMapper.findOneReadByCondition(queryWrapper);
        loadUser(list);

        return list;
    }

    private void loadUser(List<SysOptLog> list) {
        if (list == null || list.isEmpty()) {
            return;
        }

        Map<String, SysUser> userMap = sysUserService.findMap();
        list.forEach(sysOptLog -> {
            SysUser user = userMap.get(sysOptLog.getUserId());
            sysOptLog.setUserName(user == null ? "" : user.getNickName());
            sysOptLog.setParam(null);
            sysOptLog.setResult(null);
//			sysOptLog.setUserUser(SysUserUtil.getSimpleSysUser(user));
        });
    }

    private CkPageQuery getSysOptLogRequest(CkPageQuery pageQuery) {
//		condition.setOptType(SysOptLog.OPT_TYPE_SELECT);
        switch ((String) pageQuery.get("queryType")) {
            case "1":
                break;
            case "2":
                pageQuery.put("user", SecurityUtils.getUserId());
                break;
            default:
                throw new ChuangkeException("请输入正确的查询参数!");
        }
        return pageQuery;
    }

    private void saveToStore(List<SysOptLog> sysOptLogList) {
        sysOptLogList.forEach(this::saveToStore);
    }

    private void saveToStore(SysOptLog sysOptLog) {
        sysOptLog.setId(IdManager.nextId());
        if (sysOptLog.getResult() != null && sysOptLog.getResult().length() > 5000) {
            sysOptLog.setResult(sysOptLog.getResult().substring(0, 5000));
        }
        if (sysOptLog.getParam() != null && sysOptLog.getParam().length() > 5000) {
            sysOptLog.setParam(sysOptLog.getParam().substring(0, 5000));
        }
        sysOptLogMapper.insert(sysOptLog);
    }

    @Override
    public void update(String objType, String objId, String objName) {
        sysOptLogMapper.update(null, new UpdateWrapper<SysOptLog>().lambda().set(SysOptLog::getObjName, objName)
                .eq(SysOptLog::getObjType, objType).eq(SysOptLog::getObjId, objId));
    }

}
